package xyz.jcat.generator.mybatis;

import xyz.jcat.common.util.DateUtils;
import xyz.jcat.generator.mybatis.bo.JavaInfo;
import xyz.jcat.generator.mybatis.config.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yueyue
 * @Time 2017-05-15 15:05
 */
@Component
public class Generator {

    private static final Logger LOG = LoggerFactory.getLogger(xyz.jcat.generator.mybatis.Generator.class);

    private DbConfig dbConfig;

    private PersonalizedConfig personalizedConfig;

    private xyz.jcat.generator.mybatis.DataBuilder dataBuilder;
    @Autowired
    private xyz.jcat.generator.mybatis.TableInfoDao tableInfoDao;

    public void execute() throws IOException {
        //初始化生成文件相关数据
        dataBuilder = new xyz.jcat.generator.mybatis.DataBuilder(dbConfig, personalizedConfig, tableInfoDao);
        createFiles();
        String osName = System.getProperty("os.name");
        if (osName != null) {
            if (osName.contains("Mac")) {
                Runtime.getRuntime().exec("open " + personalizedConfig.getSaveDir());
            } else if (osName.contains("Windows")) {
                Runtime.getRuntime().exec("cmd /c start " + personalizedConfig.getSaveDir());
            }
        }
    }

    /**
     * 生成类文件
     *
     * @throws IOException
     */
    private void createFiles() throws IOException {
        List<JavaInfo> javaInfoList = dataBuilder.getJavaInfoList();
        FilePathConfig filePathConfig = dataBuilder.getFilePathConfig();
        PackageConfig packageConfig = dataBuilder.getPackageConfig();
        DefaultConfig defaultConfig = new DefaultConfig();
        Map<String, Object> datas = new HashMap<>();
        datas.put("packageConfig", packageConfig);
        datas.put("personalizedConfig", personalizedConfig);
        datas.put("datetime", DateUtils.format(new Date()));
        datas.put("defaultConfig", defaultConfig);
        try {
            for (JavaInfo javaInfo : javaInfoList) {
                datas.put("javaInfo", javaInfo);
                String fileName;
                if (personalizedConfig.isCreatePo()) {
                    String poMsg = xyz.jcat.generator.mybatis.BeetlUtils.getMsg(DefaultConfig.TEMPLATE_MYBATIS_PATH, DefaultConfig.TEMPLATE_PO_NAME, datas);
                    createFile(poMsg, (fileName = javaInfo.getPoName() + DefaultConfig.SUFFIX_JAVA), filePathConfig.getPoFilePath(), true);
                }
                if (personalizedConfig.isCreateDao()) {
                    String daoMsg = xyz.jcat.generator.mybatis.BeetlUtils.getMsg(DefaultConfig.TEMPLATE_MYBATIS_PATH, DefaultConfig.TEMPLATE_DAO_NAME, datas);
                    createFile(daoMsg, (fileName = javaInfo.getDaoName() + DefaultConfig.SUFFIX_JAVA), filePathConfig.getDaoFilePath(), false);
                }
                if (personalizedConfig.isCreateIService()) {
                    String serviceMsg = xyz.jcat.generator.mybatis.BeetlUtils.getMsg(DefaultConfig.TEMPLATE_MYBATIS_PATH, DefaultConfig.TEMPLATE_SERVICE_NAME, datas);
                    createFile(serviceMsg, (fileName = javaInfo.getServiceName() + DefaultConfig.SUFFIX_JAVA), filePathConfig.getServiceFilePath(), false);
                }
                if (personalizedConfig.isCreateService()) {
                    String serviceImplMsg = xyz.jcat.generator.mybatis.BeetlUtils.getMsg(DefaultConfig.TEMPLATE_MYBATIS_PATH, DefaultConfig.TEMPLATE_SERVICE_IMPL_NAME, datas);
                    createFile(serviceImplMsg, (fileName = javaInfo.getServiceImplName() + DefaultConfig.SUFFIX_JAVA), filePathConfig.getServiceImplFilePath(), false);
                }
                if (personalizedConfig.isCreateMapper()) {
                    String mapperXmlMsg = xyz.jcat.generator.mybatis.BeetlUtils.getMsg(DefaultConfig.TEMPLATE_MYBATIS_PATH, DefaultConfig.TEMPLATE_MAPPER_XML_NAME, datas);
                    createFile(mapperXmlMsg, (fileName = javaInfo.getMapperName() + DefaultConfig.SUFFIX_XML), filePathConfig.getMapperXmlFilePath(), true);
                }
            }
        } catch (IOException e) {
            LOG.error("通过beetl模板获取文件内容异常", e);
            throw new IOException(e);
        }
    }

    private void createFile(String msg, String fileName, String filePath, boolean existDelete) throws IOException {
        File file = new File(filePath + File.separator + fileName);
        if (file.exists()) {
            if (existDelete)
                file.delete();
            else
                return;
        }
        try (
                StringReader sr = new StringReader(msg);
                BufferedReader br = new BufferedReader(sr);
                FileOutputStream fos = new FileOutputStream(file);
                PrintStream ps = new PrintStream(fos);
        ) {
            String line = null;
            while ((line = br.readLine()) != null) {
                ps.println(line);
            }
            LOG.info("生成 -> {}", fileName);
        } catch (IOException e) {
            LOG.error("生成文件发生异常", e);
            throw new IOException(e);
        }
    }


    public void setDbConfig(DbConfig dbConfig) {
        this.dbConfig = dbConfig;
    }

    public void setPersonalizedConfig(PersonalizedConfig personalizedConfig) {
        this.personalizedConfig = personalizedConfig;
    }

}
